#include "bloques.h"
#include "ficheros_basico.h"

#include <string.h>
#include <sys/types.h>


superbloque SB;


int tamMB (unsigned int nbloques)
{
	
	int tam_MB;
	int modulo = nbloques % (tam_bloq * 8);
	
	if (modulo == 0)
	{
		tam_MB = nbloques / (tam_bloq * 8);
	} else {
		tam_MB = (nbloques / (tam_bloq * 8)) + 1;
	}
	
	printf("fichero_basico.c -> tamMB => valor del tam_MB: %d \n", tam_MB);
	
	return tam_MB;
	
}

int tamAI (unsigned int nbloques)
{

	int inodbl = tam_bloq/sizeof(inodo);		//TAM_INODO;

	int tam_AI;
	tam_AI = nbloques / 4;

	if((tam_AI % inodbl) == 0)
	{
		tam_AI = tam_AI / inodbl;
	}
	else{
		tam_AI = (tam_AI / inodbl) + 1;
	}

	printf("fichero_basico.c -> tamAI => valor del tam_AI: %d \n", tam_AI);

	return tam_AI;

} 


void initSB (unsigned int nbloques)
{

	char buff[tam_bloq];

	SB.primerbloque_MB = 1;
	SB.ultimobloque_MB = tamMB(nbloques);
	SB.primerbloque_AI = SB.ultimobloque_MB + 1;
	SB.ultimobloque_AI = tamMB(nbloques) + tamAI(nbloques);
	SB.primerbloque_datos = SB.ultimobloque_AI + 1;
	SB.ultimobloque_datos = nbloques - 1;
	SB.inodoraiz = 0;
	SB.primerinodo_libre = 0; 
	SB.bloques_libres = nbloques - (SB.ultimobloque_AI + 1);
	SB.inodos_libres = nbloques / 4;
	SB.total_bloques = nbloques;
	SB.total_inodo = nbloques / 4;


	memset(buff,0,tam_bloq);
	memcpy(buff,&SB,sizeof(superbloque));
	bwrite(0,buff);
	
	printf("fichero_basico.c -> initSB => Superbloque inicializado correctamente \n ");
	
}


void initMB (unsigned int nbloques)
{

	unsigned char buff[tam_bloq];
	memset(buff,0,tam_bloq);
	
	int i;
	for (i = SB.primerbloque_MB;i <= SB.ultimobloque_MB; i++){
		if (bwrite(i, buff) == -1) {
			printf("fichero.basico.c -> initMB => Error al escribir el bloque %d \n", i); break;
		}
	}

	for (i = 0;i <= SB.primerbloque_AI; i++){
		//escribir_bit(i,1);
	}

	printf("fichero_basico.c -> initMB => Mapa de Bits inicializado correctamente \n");

}


void initAI (unsigned int nbloques)
{

	if (bread(0,(char *)&SB) == -1){
		printf("ficheros_basico.c -> initAI => Error al leer el inodo \n");
	}

	//Inicializamos el inodo
	inodo inod;

	inod.tipo = 0;	
	inod.tamano = 0;
	inod.fechaMod = time(NULL);	
	inod.bloques_asignados = 0;	
	
	int i, j;
	
	for(i = 0; i < 8; i++){
		inod.punteros_directos[i] = -1;
	}
	
	for(i = 0; i < 3; i++){
		inod.punteros_indirectos[i] = -1;
	}
	
	unsigned char buff[tam_bloq];

	int ninodo = 0;

	//Rellenamos con 16 inodos cada uno de los bloques del array de inodos
	for(i=SB.primerbloque_AI; i<=SB.ultimobloque_AI; i++){

		memset(buff, 0, tam_bloq);

		for(j=0; j<(tam_bloq/sizeof(inodo)); j++){

			//Actualizamos la fecha de modificacion
			inod.fechaMod= time(NULL);

			//Apuntamos al siguiente inodo libre
			if((ninodo < SB.total_inodo - 1)){
				inod.punteros_directos[0] = ninodo + 1;
              		}

			//Último inodo
			else if(ninodo == SB.total_inodo - 1){
				inod.punteros_directos[0] = -1;
			}

			memcpy(&buff[j * sizeof(inodo)], &inod, sizeof(inodo));
              		ninodo++;
        	}

		//Guardamos cambios en el bloque correspondiente
		bwrite(i, buff);
      	}


	printf("ficheso_basico.c -> intAI => Array de Inodos inicializado correctamente!!! \n");

}


void leerSB(){

	unsigned char buff[tam_bloq];
	if (bread(0,buff) == -1){
		printf("ficheros_basico.c -> leerSB => Error el leer el bloque \n");
	}
	memcpy(&SB,buff,sizeof(superbloque));
	
	printf("---------- Información SUPERBLOQUE ----------\n");
	printf("Número del primer bloque del mapa de bits: %d\n",SB.primerbloque_MB);     
	printf("Número del último bloque del mapa de bits: %d\n",SB.ultimobloque_MB);
	printf("Número del primer bloque del array de inodos: %d\n",SB.primerbloque_AI);
	printf("Número del último bloque del array de inodos: %d\n",SB.ultimobloque_AI);
	printf("Número del primer bloque de datos: %d\n",SB.primerbloque_datos);
	printf("Número del último bloque de datos: %d\n",SB.ultimobloque_datos);
	printf("Número del inodo del directorio raíz: %d\n",SB.inodoraiz);
	printf("Número del primer inodo libre: %d\n",SB.primerinodo_libre);
	printf("Número de bloques libres: %d\n",SB.bloques_libres);
	printf("Número de inodos libres: %d\n",SB.inodos_libres);
	printf("Cantidad total de bloques: %d\n",SB.total_bloques);
	printf("Cantidad total de inodos: %d\n",SB.total_inodo);

}

void escribir_bit(int nbloque, int num){

	int pos_byte = nbloque / 8;  //posicion del byte dentro del MB
	int pos_bit = nbloque % 8;   //posicion del bit dentro del byte
	
	unsigned char mapa_bits[tam_bloq];
	unsigned char mascara = 128;  //10000000
	
	//Obtenemos el bloque del mapa de bits a leer
	int bloque_MB = (nbloque / (tam_bloq * 8));
	
	if (bread((SB.primerbloque_MB + bloque_MB),mapa_bits) == -1){
		printf(" ficheros_basico.c -> escribir_bit => Error al leer el bloque %d \n", SB.primerbloque_MB + bloque_MB);
	}
	
	//Diferenciamos si el valor del bit a escribir es 0 (libre) o 1 (ocupado)
	if (num == 1){
		if (pos_bit > 0){
			mascara >>= pos_bit;  // Desplazamiento de bits a la derecha
			mapa_bits[pos_byte] |= mascara;
		}
	} else { 
		if (pos_bit > 0){
			mascara >>= pos_bit;
			mapa_bits[pos_byte] &= ~mascara;
		}
	}
	
	//Guardamos los cambios
	bwrite(bloque_MB, mapa_bits);

}

unsigned int leer_bit(unsigned int nbloque){

	//Obtenemos el bloque del mapa de bits a leer
	unsigned int bloque_MB = (nbloque / (tam_bloq * 8));
	
	unsigned char mapa_bits[tam_bloq];
	memset(mapa_bits, 0, tam_bloq);
	
	if (bread(bloque_MB, mapa_bits) == -1){
		printf("ficheros_basico.c -> leer_bit => Error al leer el bloque %d \n", bloque_MB);
		return -1;
	}
	
	int pos_byte = nbloque / 8;  //posicion del byte dentro del MB
	int pos_bit = nbloque % 8;	 //posicion de bit dentro del byte
	
	unsigned char mascara = 128; //10000000

	mapa_bits[pos_byte] &= mascara;
	  
	// Distinguimos los casos  
	if (mapa_bits[pos_byte % tam_bloq] == 0){ //Todos son 0's
		return 0;
	} else if (mapa_bits[pos_byte % tam_bloq] == 255){ //Todos son 1's
		return 1;
	} else {
	
		if (pos_bit > 0) {
			mascara >>= pos_bit;  //Desplazamiento de bits a la derecha
		}
		
		if (mapa_bits[pos_byte % tam_bloq]){
			return 1;
		} else {
			return 0;
		}
	}
}

int reservar_bloque(){
	
	unsigned char buff[tam_bloq];
	unsigned char mascara = 128;
	
	if (bread(0,buff) == -1){
		printf("ficheros_basico.c -> reservar_bloque => Error al leer el bloque \n");
		return -1;
	}
	memcpy(&SB, buff, sizeof(superbloque));
	
	//Calculamos en que bloque esta el primer bloque de datos del MB y lo insertamos en el buff
	unsigned int nbloque_mb = SB.primerbloque_datos / (tam_bloq * 8);
	nbloque_mb = nbloque_mb + 1;

	int pos_byte = nbloque_mb / 8;
	
	if (bread(nbloque_mb, buff) == -1){
		printf("ficheros_basico.c -> reservar_bloque => Error al leer el bloque \n");
		return -1;	
	}
	
	//Ignoramos los bytes has que nos encontremos con el caso 1111 1111
	while(buff[pos_byte % tam_bloq] == 255){
		
		pos_byte++;
		if((pos_byte % tam_bloq) == 0){
			nbloque_mb++;
			if (bread(nbloque_mb, buff) == -1){
				printf("ficheros_basico.c -> reservar_bloque => Error al leer el bloque \n");
				return -1;	
			}
			pos_byte++;
		}
	}
	
	//identificamos el bloque libre
	int i = 0;

	while(buff[pos_byte % tam_bloq] & mascara){
		buff[pos_byte % tam_bloq] <<= 1;
		i++;
	}

	int nbloque = pos_byte * 8;
	nbloque = nbloque + i;

	escribir_bit(nbloque,1);

	printf("ficheros_basico.c -> reservar_Bloque => Bloque reservado %d \n", nbloque);
	return nbloque;
}

int liberar_bloque(unsigned int nbloque){
	
	if (bread(0, &SB) == -1){
		printf("ficheros_basico.c -> liberar_bloque => Error al leer el bloque \n");
		return -1;
	}
	
	unsigned char buff[tam_bloq];
	memset(buff,0,tam_bloq);
		
	if (bwrite(0,buff) == -1){
		printf("ficheros_basico.c -> liberar_bloque => Error al escribir en el bloque %d \n", nbloque);
		return -1;
	}
	
	escribir_bit(nbloque,0);
	SB.bloques_libres = SB.bloques_libres + 1;  //Actualizamos el MB añadiendo el bloque libre
	
	printf("ficheros_basico.c -> liberar_bloque => Bloque %d liberado \n", nbloque);
	
	return 0;
}

int escribir_inodo(inodo inod, int ninodo){

	if (bread(0, &SB) == -1){
		printf("ficheros_basico.c -> liberar_bloque => Error al leer el bloque \n");
		return -1;
	}
	
	unsigned char buff[tam_bloq];
	
	memset(buff, 0, tam_bloq);
	
	if (bread(SB.primerbloque_AI + (ninodo / (tam_bloq/sizeof(inodo))),buff) == -1){
		printf("ficheros_bascio.c -> escribir_inodo => Error al leer el inodo %d \n", ninodo);
		return -1;
	}
	
	inod.fechaMod = time(NULL);
	
	memcpy(&buff[(ninodo % (tam_bloq/sizeof(inodo)))*sizeof(inodo)], &inod, sizeof(inodo));
	
	if (bwrite(SB.primerbloque_AI + (ninodo/(tam_bloq/sizeof(inodo))), buff) == -1){
		printf("ficheros_basico.c -> escribir_inodo => Error al escribir el inodo %d \n", ninodo);
		return -1;
	}
	
	return 0;
}

inodo leer_inodo(unsigned int ninodo){

	int pos_bloque_ai = (ninodo / (tam_bloq / sizeof(inodo))) + SB.primerbloque_AI;
	int pos_inodo = ninodo % (tam_bloq / sizeof(inodo));
	
	unsigned char buff[tam_bloq];
	memset(buff, 0, tam_bloq);
	
	if (bread(pos_bloque_ai, buff) == -1){
		printf("ficheros_basico -> leer_inodo => Error al leer el inodo %d \n", ninodo);
	}
	
	inodo inod;
	
	//Insertamos en inod toda la informacion
	memcpy(&inod, &buff[pos_inodo * sizeof(inodo)], sizeof(inodo));
	
	return inod;
}

int reservar_inodo(int tipo){
	
	unsigned char buff[tam_bloq];
	
	if (bread(0,(char *)&SB) == -1){
		printf("ficheros_basico.c -> reservar_inodo => Error al leer el inodo \n");
		return -1;
	}
	
	if (SB.inodos_libres > 0){
	
		inodo ino;
		int i;
		
		int lista;
	
		//obtenemos el inodo libre
		int reserva = SB.primerinodo_libre;
	
		ino = leer_inodo(reserva);
	
		//inicializamos los valores del inodo
		ino.tipo = tipo;
		ino.tamano = 0;
		ino.fechaMod = time(NULL);
		ino.bloques_asignados = 0;
		ino.enlaces_directorio = 1;
	
		lista = ino.punteros_directos[0];
		ino.punteros_directos[0] = -1;
	
		if (escribir_inodo(ino,reserva) == -1){
			printf("ficheros_basico.c -> reservar_inodo => Error al escribir el inodo");
		}
	
		SB.primerinodo_libre = lista;
		SB.inodos_libres = SB.inodos_libres - 1;
	
		if (bwrite(0,(char *)&SB) == -1){
			printf("ficheros_basico.c -> reservar_inodo => Error al escribir el bloque \n");
			return -1;
		}
	
		printf("ficheros_basico.c -> reservar_inodo => Inodo %d reservado \n", reserva);
		return reserva;
	
	} else {
		printf("ficheros_basico.c -> reservar_inodo => No quedan inodos libres");
		return -1;
	}
	
}

void liberar_inodo(int ninodo){
	
	int i, j, k = 0;
	inodo inod;
	inodo array[tam_bloq/sizeof(inodo)];
	
	int PuntBl = tam_bloq / sizeof(unsigned int);
	unsigned char buff[tam_bloq];
	unsigned int bl_indirecto[PuntBl], bl_indirecto2[PuntBl], bl_indirecto3[PuntBl];
	
	inod = leer_inodo(ninodo);
	
	//Liberamos los bloques de los punteros directos de un inodo
	for(i = 0; i < 8; i++){
		if (inod.punteros_directos[i] != 0){
			liberar_bloque(inod.punteros_directos[i]);
		}
	}
	
	//Liberamos los bloques que apuntan al puntero indirecto 0 de un inodo
	if(inod.punteros_indirectos[0] != 0){
		if (bread(inod.punteros_indirectos[0], bl_indirecto) == -1){
			printf("ficheros_basico.c -> liberar_inodo => Error al leer el bloque %d \n", inod.punteros_indirectos[0]);
		}
		
		for(i = 0; i < PuntBl; i++){
			if(bl_indirecto[i] != 0){
				liberar_bloque(bl_indirecto[i]);
			}
		}
		liberar_bloque(inod.punteros_indirectos[0]);
	}
	
	//Liberamos los bloques que apuntan al puntero indirecto 1 de un inodo
	if(inod.punteros_indirectos[1] != 0){
		if (bread(inod.punteros_indirectos[1],bl_indirecto) == -1){
			printf("ficheros_basico.c -> liberar_inodo => Error al leer el bloque %d \n", inod.punteros_indirectos[1]);
		}
		for(i = 0; i < PuntBl; i++){
			if(bl_indirecto[i]!=0){
				if (bread(bl_indirecto[i],bl_indirecto2) == -1){
					printf("ficheros_basico.c -> liberar_inodo => Error al leer el bloque %d \n", bl_indirecto[i]);
				}
				for(j = 0; j < PuntBl; j++){
					if(bl_indirecto2[j]!=0){
						liberar_bloque(bl_indirecto2[j]);
					}
				}
				liberar_bloque(bl_indirecto[i]);
			}
		}
		liberar_bloque(inod.punteros_indirectos[1]);
	}
	
	//Liberamos los bloques que apuntan al puntero indirecto 2 de un inodo
	if(inod.punteros_indirectos[2] != 0){
		if (bread(inod.punteros_indirectos[2],bl_indirecto) == -1){
			printf("ficheros_basico.c -> liberar_inodo => Error al leer el bloque %d \n", inod.punteros_indirectos[2]);
		}
		for(i = 0; i < PuntBl; i++){
			if(bl_indirecto[i]!=0){
				if (bread(bl_indirecto[i],bl_indirecto2) == -1){
					printf("ficheros_basico.c -> liberar_inodo => Error al leer el bloque %d \n", bl_indirecto[i]);
				}
				for(j = 0; j < PuntBl; j++){
					if(bl_indirecto2[j]!=0){
						if (bread(bl_indirecto[j],bl_indirecto3) == -1){
							printf("ficheros_basico.c -> liberar_inodo => Error al leer el bloque %d \n", bl_indirecto[j]);
						}
						for(k = 0; k < PuntBl; k++){
							if(bl_indirecto3[k]!=0){
								liberar_bloque(bl_indirecto3[k]);
							}
						}
						liberar_bloque(bl_indirecto2[j]);
					}
				}
				liberar_bloque(bl_indirecto[i]);
			}
		}
		liberar_bloque(inod.punteros_indirectos[2]);
	}
	
	SB.primerinodo_libre = SB.inodos_libres + 1;
	
	inod.tamano = SB.primerinodo_libre;
	inod.tipo = 0;
	inod.bloques_asignados = 0;
	inod.fechaMod = 0;
	inod.enlaces_directorio = 0;

	SB.primerinodo_libre = ninodo;

	if (bread(SB.primerbloque_AI + (ninodo / tam_bloq/sizeof(inodo)),array) == -1){
		printf("ficheros_basico.c -> liberar_inodo => Error al leeer el bloque %d \n", SB.primerbloque_AI + (ninodo / tam_bloq/sizeof(inodo)));
	}
	array[ninodo % tam_bloq/sizeof(inodo)] = inod;
	if (bwrite(SB.primerbloque_AI + (ninodo / tam_bloq/sizeof(inodo)),array) == -1){
		printf("ficheros_basico.c -> liberar_inodo => Error al escribir el bloque %d \n", SB.primerbloque_AI + (ninodo / tam_bloq/sizeof(inodo)));
	}
	
	memcpy(buff,&SB,sizeof(superbloque)); 
	if (bwrite(0,buff) == -1){
		printf("ficheros_basico.c -> liberar_inodo => Error al escribir el bloque \n");
	}
	
}

int traducir_bloque_inodo(int ninodo, int nbloque, char reservar){
		
	//aqui es donde leeremos los punteros a los que apuntan los punteros indirectos	
	int lectura_punteros[256],lectura_punteros2[256];//el 256 es por los numeros de punteros que hay en un bloque
	//calculo que servira para determinar el bloque en el caso de que no este en punteros directos	
	int cal1 = nbloque - 8;
	//este será el inodo que trataremos	
	inodo in;
	in = leer_inodo(ninodo);
	//en el caso en que reservar valga 0, la utilizaremos para consultar
	if (reservar=0){
		//si el bloque se encuentra en los punteros directos(aqui son 8 por definicion de la practica)
		if(0<=nbloque<8){
			return in.punteros_directos[nbloque];//devolvemos el bloque apuntado por el puntero directo correspondiente
		//si el bloque se encuentra en el puntero indirecto 0		
		}else if(8<=nbloque<256+8){
			bread(in.punteros_indirectos[0], lectura_punteros);//leemos el bloque de punteros apuntado por el puntero indirecto 0
			printf("Puntero 1 (%d) está en el Bloque:  %d \n", cal1, in.punteros_indirectos[0]);	///////
			return lectura_punteros[cal1]; //Devolvemos el bloque fisico
		}else if(256+8<=nbloque<256*256+256+8){
			//leemos el bloque de punteros apuntados por el puntero indirecto 1			
			bread(in.punteros_indirectos[1], lectura_punteros);
			//leemos el bloque apuntado por el bloque nbloque-264/256
			bread(lectura_punteros[nbloque-264/256], lectura_punteros2);
			//devolvemos el bloque
			return lectura_punteros2[nbloque-264%256];
		}else if(256*256+256+8<=nbloque<256*256*256+256*256+256+8){
			//leemos el bloque de punteros apuntados por el puntero indirecto 1			
			bread(in.punteros_indirectos[2], lectura_punteros);
			//leemos el bloque apuntado por el bloque nbloque-264/256
			bread(lectura_punteros[nbloque-264+256*256/256*256], lectura_punteros);
			//devolvemos el bloque
			bread(lectura_punteros[nbloque-264+256*256/256], lectura_punteros);
			return lectura_punteros2[nbloque-264+256*256%256];		
		}
	}else if(reservar==1){
		//si el bloque se encuentra en los punteros directos(aqui son 8 por definicion de la practica)
		if((0<=nbloque) && (nbloque<8)){
			//si existe bloque fisico devolvemos su posicion
			if(in.punteros_directos[nbloque] > 0){
				return in.punteros_directos[nbloque];
			}//NO existe bloque fisico
			else if(in.punteros_directos[nbloque] == -1){
				in.punteros_directos[nbloque] = reservar_bloque();
				in.bloques_asignados = in.bloques_asignados + 1;
				escribir_inodo(in,ninodo);					
				return in.punteros_directos[nbloque];
				}
			}
		//si el bloque se encuentra en el puntero indirecto 0		
		}else if(8<=nbloque<256+8){
			if(in.punteros_indirectos[0] > 0){
				bread(in.punteros_indirectos[0], lectura_punteros);
					//printf("Puntero 1 (%d) está en el Bloque: %d \n", bloque_logico, in.pindirectos[0]);	///////			
					if(lectura_punteros[nbloque-8] == 0){
						lectura_punteros[nbloque-8] = reservar_bloque();
						bwrite(in.punteros_indirectos[0], lectura_punteros);
						in.bloques_asignados = in.bloques_asignados + 1;
						escribir_inodo(in,ninodo);
					}
					return lectura_punteros[nbloque-8]; //Devolvemos bloque fisico
			} else if(in.punteros_indirectos[0] == -1){
					in.punteros_indirectos[0] = reservar_bloque(); 
					bread(in.punteros_indirectos[0], lectura_punteros);
					memset(lectura_punteros, 0, tam_bloq);
					//printf("Puntero 1 (%d) está en el Bloque:  %d \n", bloque_logico, in.pindirectos[0]);	///////					
					lectura_punteros[nbloque-8] = reservar_bloque();					
					in.bloques_asignados = in.bloques_asignados + 1;
					bwrite(in.punteros_indirectos[0], lectura_punteros);
					escribir_inodo(in,ninodo);		
					return lectura_punteros[nbloque-8]; //Devolvemos bloque fisico
			}
				
		} else if ((256+8 <= nbloque) && (nbloque < ((256*256)+256+8))){
			if(in.punteros_indirectos[1] > 0){
					bread(in.punteros_indirectos[1], lectura_punteros);
					
					if(lectura_punteros[nbloque-(8 + 256)/256] > 0){

						//printf("Puntero 1 (%d) está en el Bloque:  %d \n", bloque_logico/NUM_PUNTEROS, in.pindirectos[1]);	///////			
						bread(lectura_punteros[nbloque-(8 + 256)/256], lectura_punteros2);

						//printf("Puntero 2 (%d) está en el Bloque:  %d \n", bloque_logico%NUM_PUNTEROS, lectura_punteros[bloque_logico/NUM_PUNTEROS]);	///////

						if(lectura_punteros2[nbloque-(8 + 256) % 256] == 0){
							
							lectura_punteros2[nbloque-(8 + 256) % 256] = reservar_bloque();
							bwrite(lectura_punteros[(nbloque-(8 + 256)/256)], lectura_punteros2);
		
							in.bloques_asignados = in.bloques_asignados + 1;
							escribir_inodo(in, ninodo);
						}
						
						return lectura_punteros2[nbloque-(8 + 256) % 256]; //Devolvemos bloque fisico
					}
					else{ 
						
						
						lectura_punteros[nbloque-(8 + 256)/256] = reservar_bloque();

						bwrite(in.punteros_indirectos[1], lectura_punteros);

						//printf("Puntero 1 (%d) está en el Bloque:  %d \n", bloque_logico/NUM_PUNTEROS, in.pindirectos[1]);	///////////			

						bread(lectura_punteros[nbloque-(8 + 256)/256], lectura_punteros2);

						//printf("Puntero 2 (%d) está en el Bloque:  %d \n", bloque_logico%NUM_PUNTEROS, buffer_punteros[bloque_logico/NUM_PUNTEROS]);	//////////

						
						lectura_punteros2[nbloque-(8 + 256) % 256] = reservar_bloque();

						in.bloques_asignados = in.bloques_asignados + 1;
						bwrite(lectura_punteros[nbloque-(8 + 256)/256], lectura_punteros2);
		
						escribir_inodo(in,ninodo);
		
						return lectura_punteros2[nbloque-(8 + 256) % 256]; //Devolvemos bloque fisico
						
					}		

				}
				else if(in.punteros_indirectos[1] == -1){

					in.punteros_indirectos[1] = reservar_bloque();

					bread(in.punteros_indirectos[1], lectura_punteros);
									
					lectura_punteros[nbloque-(8 + 256)/256] = reservar_bloque();

					bwrite(in.punteros_indirectos[1], lectura_punteros);

					//printf("Puntero 1 (%d) está en el Bloque:  %d \n", bloque_logico/NUM_PUNTEROS, in.pindirectos[1]);	///////////			

					bread(lectura_punteros[nbloque-(8 + 256)/256], lectura_punteros2);

					//printf("Puntero 2 (%d) está en el Bloque:  %d \n", bloque_logico%NUM_PUNTEROS, buffer_punteros[bloque_logico/NUM_PUNTEROS]);	//////////

					
					lectura_punteros2[nbloque-(8 + 256) % 256] = reservar_bloque();
					in.bloques_asignados = in.bloques_asignados + 1;

					bwrite(lectura_punteros[nbloque-(8 + 256)/256], lectura_punteros2);

					escribir_nodo(in,ninodo);

					return lectura_punteros2[nbloque-(8 + 256) % 256]; //Devolvemos bloque fisico

				}
			
		}else if(256*256+256+8<=nbloque<256*256*256+256*256+256+8){
			if(in.punteros_indirectos[2] > 0){
					bread(in.punteros_indirectos[2], lectura_punteros);

					if((lectura_punteros[nbloque-(8+256+256*256)/(256*256)]) > 0){

						//printf("Puntero 1 (%d) está en el Bloque:  %d \n", bloque_logico/(NUM_PUNTEROS*NUM_PUNTEROS), in.pindirectos[2]);	///////
						//int print = (buffer_punteros[bloque_logico/(NUM_PUNTEROS*NUM_PUNTEROS)]);///////////////

						bread(lectura_punteros[nbloque-(8+256+256*256)/(256*256)], lectura_punteros2);
						int bloque_aux = nbloque-((8+256+256*256) % (256*256));

						//print = lectura_punteros2[bloque_aux/NUM_PUNTEROS];

						if(lectura_punteros2[bloque_aux/256] > 0){

							//printf("Puntero 2 (%d) está en el Bloque:  %d \n", (bloque_aux/NUM_PUNTEROS), lectura_punteros[bloque_logico/(NUM_PUNTEROS*NUM_PUNTEROS)]);	///////
	
							bread(lectura_punteros2[bloque_aux/256], lectura_punteros);

							//printf("Puntero 3 (%d) está en el Bloque %d \n", bloque_aux%NUM_PUNTEROS, print);

							if(lectura_punteros[nbloque-(8+256+256*256) % (256)] == 0){
								lectura_punteros[nbloque-(8+256+256*256) % (256)] = reservar_bloque();
								bwrite(lectura_punteros2[bloque_aux/256], lectura_punteros);
								in.bloques_asignados = in.bloques_asignados + 1;
								escribir_inodo(in,ninodo);
							}
						
							return lectura_punteros[nbloque-(8+256+256*256) % (256)]; 
						}
						else{ 
				
							lectura_punteros2[bloque_aux/256] = reservar_bloque();

							//printf("Puntero 2 (%d) está en el Bloque:  %d \n", (bloque_aux/NUM_PUNTEROS), lectura_punteros[bloque_logico/(NUM_PUNTEROS*NUM_PUNTEROS)]);	///////

							bwrite(lectura_punteros[nbloque-(8+256+256*256)/(256*256)], lectura_punteros2);

							bread(lectura_punteros2[bloque_aux/256], lectura_punteros);

							//printf("Puntero 3 (%d) está en el Bloque:  %d \n", (bloque_aux%NUM_PUNTEROS), lectura_punteros2[bloque_aux/NUM_PUNTEROS]);	///////

							
							lectura_punteros[nbloque-(8+256+256*256) % (256)] = reservar_bloque();
							in.bloques_asignados = in.bloques_asignados + 1;

							bwrite(lectura_punteros2[bloque_aux/256], lectura_punteros);
							escribir_inodo(in,ninodo);

							return (lectura_punteros[nbloque-(8+256+256*256) % (256)]);	//Devolvemos bloque fisico	

						}					

						
					}
					else{ 
						//printf("Puntero 1 (%d) está en el Bloque:  %d \n", bloque_logico/(NUM_PUNTEROS*NUM_PUNTEROS), in.pindirectos[2]);	///////
						lectura_punteros[nbloque-(8+256+256*256)/(256*256)] = reservar_bloque();

						bwrite(in.punteros_indirectos[2], lectura_punteros);

						bread(lectura_punteros[nbloque-(8+256+256*256)/(256*256)], lectura_punteros2);

						int bloque_aux = nbloque-(8+256+256*256)%(256*256);

						//printf("Puntero 2 (%d) está en el Bloque:  %d \n", (bloque_aux/NUM_PUNTEROS), lectura_punteros[bloque_logico/(NUM_PUNTEROS*NUM_PUNTEROS)]);	///////

						lectura_punteros2[bloque_aux/256] = reservar_bloque();

						bwrite(lectura_punteros[nbloque-(8+256+256*256)/(256*256)], lectura_punteros2);

						bread(lectura_punteros2[bloque_aux/256], lectura_punteros);

						//printf("Puntero 3 (%d) está en el Bloque:  %d \n", (bloque_aux%NUM_PUNTEROS), lectura_punteros2[bloque_aux/NUM_PUNTEROS]);	///////

						
						lectura_punteros[nbloque-(8+256+256*256) % (256)] = reservar_bloque();
						in.bloques_asignados = in.bloques_asignados + 1;

						bwrite(lectura_punteros2[bloque_aux/256], lectura_punteros);

						escribir_inodo(in,ninodo);

						return (lectura_punteros[nbloque-(8+256+256*256) % (256)]);	//Devolvemos bloque fisico	

					}

				}
				else if(in.punteros_indirectos[2] == -1){
				
					
					in.punteros_indirectos[2] = reservar_bloque();

					bread(in.punteros_indirectos[2], lectura_punteros);

					//printf("Puntero 1 (%d) está en el Bloque:  %d \n", bloque_logico/(NUM_PUNTEROS*NUM_PUNTEROS), in.pindirectos[2]);	///////

					
					lectura_punteros[nbloque-(8+256+256*256)/(256*256)] = reservar_bloque();

					bwrite(in.punteros_indirectos[2], lectura_punteros);

					bread(lectura_punteros[nbloque-(8+256+256*256)/(256*256)], lectura_punteros2);

					int bloque_aux = nbloque-(8+256+256*256)%(256*256);

					//printf("Puntero 2 (%d) está en el Bloque:  %d \n", (bloque_aux/NUM_PUNTEROS), lectura_punteros[bloque_logico/(NUM_PUNTEROS*NUM_PUNTEROS)]);	///////

					
					lectura_punteros2[bloque_aux/256] = reservar_bloque();

					bwrite(lectura_punteros[nbloque-(8+256+256*256)/(256*256)], lectura_punteros2);

					bread(lectura_punteros2[bloque_aux/256], lectura_punteros);

					//printf("Puntero 3 (%d) está en el Bloque:  %d \n", (bloque_aux%NUM_PUNTEROS), lectura_punteros2[bloque_aux/NUM_PUNTEROS]);	///////

					lectura_punteros[nbloque-(8+256+256*256)%(256)] = reservar_bloque();
					in.bloques_asignados = in.bloques_asignados + 1;

					bwrite(lectura_punteros2[bloque_aux/256], lectura_punteros);

					escribir_inodo(in,ninodo);

					return (lectura_punteros[nbloque-(8+256+256*256)%(256)]);	//Devolvemos bloque fisico	

				}
			}
}